package cn.jstars.datatocloud.modules.dict.task;

import cn.jstars.datatocloud.common.cache.Cache;
import cn.jstars.datatocloud.common.consts.Consts.DBConst;
import cn.jstars.datatocloud.common.consts.Consts.DataType;
import cn.jstars.datatocloud.common.utils.DataUtil;
import cn.jstars.datatocloud.common.utils.PageUtil;
import cn.jstars.datatocloud.modules.base.MqService;
import cn.jstars.datatocloud.modules.dict.entity.Customer;
import cn.jstars.datatocloud.modules.dict.entity.DictUser;
import cn.jstars.datatocloud.modules.dict.entity.Flight;
import cn.jstars.datatocloud.modules.dict.entity.Toiassets;
import cn.jstars.datatocloud.modules.dict.entity.Treedata;
import cn.jstars.datatocloud.modules.dict.service.DictService;
import cn.jstars.datatocloud.modules.heart.task.HeartTask;
import com.alibaba.fastjson.JSON;
import com.google.common.collect.Maps;
import org.nutz.lang.Lang;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 字典数据级联任务类
 *
 * @author Elvish
 */
public class DictTask implements Runnable {

    private static final Logger LOGGER = LoggerFactory.getLogger(HeartTask.class);

    private MqService mqService;
    private DictService dictService;

    public DictTask(MqService mqService, DictService dictService) {
        this.mqService = mqService;
        this.dictService = dictService;
    }

    @Override
    public void run() {
        ExecutorService executorService = Executors.newFixedThreadPool(5);

        executorService.submit(this::sendTreedata);
        executorService.submit(this::sendToiassets);
        executorService.submit(this::sendDictUser);
        executorService.submit(this::sendCustomer);
        executorService.submit(this::sendFlight);

        executorService.shutdown();
    }

    /**
     * 发送班次数据
     */
    private void sendFlight() {


        try {
            List<Flight> dataList = dictService.getFlight();

            if (Lang.isEmpty(dataList)) {
                LOGGER.error("班次数据为空");
                return;
            }

            for (Flight flight : dataList) {
                flight.setFlightFactoryId(Cache.factoryId);
            }

            Map<String, Object> dataMap = Maps.newHashMap();
            dataMap.put("type", "Flight");
            dataMap.put("data", JSON.toJSONString(dataList));

            // 封装发送数据
            String sendMsg = DataUtil.getMessage(DataType.DICT_DATA, DBConst.BASE_DATABASE, DBConst.DEV_FLIGHT,
                Cache.factoryId, dataMap);

            // 发送
            mqService.convertAndSend(Cache.cloudMQQueueName, sendMsg);
        } catch (Exception e) {
            LOGGER.error("级联班次数据失败", e);
        }

    }

    /**
     * 发送机台字典数据
     */
    private void sendToiassets() {
        try {
            // 获取机台数据
            List<Toiassets> dataList = dictService.getToiassets();

            if (Lang.isEmpty(dataList)) {
                LOGGER.error("机台数据为空");
                return;
            }

            // 转换数据编码
            replaceMachinePrefix(dataList);

            Map<String, Object> dataMap = Maps.newHashMap();
            dataMap.put("type", "Toiassets");
            dataMap.put("data", JSON.toJSONString(dataList));

            // 封装发送数据
            String sendMsg = DataUtil.getMessage(DataType.DICT_DATA, DBConst.BASE_DATABASE, DBConst.TOIASSETS,
                Cache.factoryId, dataMap);

            // 发送云端
            mqService.convertAndSend(Cache.cloudMQQueueName, sendMsg);
        } catch (Exception e) {
            LOGGER.error("发送机台资产数据异常", e);
        }
    }

    /**
     * 发送用户数据
     */
    private void sendDictUser() {
        try {
            // 获取用户字典数据
            List<DictUser> dataList = dictService.getUserList();

            if (Lang.isEmpty(dataList)) {
                LOGGER.error("用户数据为空");
                return;
            }

            // 更新云端factoryId编码
            for (DictUser dictUser : dataList) {
                dictUser.setFactoryId(Cache.factoryId);
            }

            Map<String, Object> dataMap = Maps.newHashMap();
            dataMap.put("type", "DictUser");
            dataMap.put("data", JSON.toJSONString(dataList));

            // 封装发送数据
            String sendMsg = DataUtil.getMessage(DataType.DICT_DATA, DBConst.BASE_DATABASE, DBConst.DICT_USER,
                Cache.factoryId, dataMap);

            // 发送
            mqService.convertAndSend(Cache.cloudMQQueueName, sendMsg);
        } catch (Exception e) {
            LOGGER.error("发送dict_user数据异常", e);
        }
    }

    /**
     * 发送dev_treedata数据
     */
    private void sendTreedata() {

        try {
            // 获取数据
            List<Treedata> dataList = dictService.getTreedata();

            if (Lang.isEmpty(dataList)) {
                LOGGER.error("dev_treedata数据为空");
                return;
            }

            String replaceStr = Cache.factoryId.substring(0, 8);
            // 替换型号编码
            for (Treedata treedata : dataList) {

                String dictCodePrefix = treedata.getDictCode().substring(0, 8);
                String dictCode = treedata.getDictCode().replaceAll(dictCodePrefix, replaceStr);
                treedata.setDictCode(dictCode);

                // 工厂级别不替换
                if (!"suoya1050003".equals(treedata.getTypeId())) {
                    String updictCodePrefix = treedata.getUpDictCode().substring(0, 8);
                    String updictCode = treedata.getUpDictCode().replaceAll(updictCodePrefix, replaceStr);
                    treedata.setUpDictCode(updictCode);
                }

            }

            // 组装数据
            Map<String, Object> dataMap = Maps.newHashMap();
            dataMap.put("type", "Treedata");
            dataMap.put("data", JSON.toJSONString(dataList));

            // 封装发送数据
            String sendMsg = DataUtil.getMessage(DataType.DICT_DATA, DBConst.BASE_DATABASE, DBConst.DEV_TREEDATA,
                Cache.factoryId, dataMap);

            // 发送
            mqService.convertAndSend(Cache.cloudMQQueueName, sendMsg);
        } catch (Exception e) {
            LOGGER.error("发送dev_treedata数据异常", e);
        }
    }

    /**
     * 发送dict_customer数据
     */
    private void sendCustomer() {

        while (true) {
            try {

                // 查询数据，5000一查
                List<Customer> customers = dictService.getCustomers();
                // 没有未级联数据，不再查询
                if (Lang.isEmpty(customers)) {
                    break;
                }
                // 封装factoryId
                for (Customer customer : customers) {
                    customer.setFactoryId(Cache.factoryId);
                }

                // 切分数据
                List<List<Customer>> pageList = PageUtil.paging(customers, 500);

                for (List<Customer> list : pageList) {

                    // 组装数据
                    Map<String, Object> dataMap = Maps.newHashMap();
                    dataMap.put("type", "Customer");
                    dataMap.put("data", JSON.toJSONString(list));

                    // 封装发送数据
                    String sendMsg = DataUtil.getMessage(DataType.DICT_DATA, DBConst.BASE_DATABASE,
                        DBConst.DICT_CUSTOMER, Cache.factoryId, dataMap);

                    try {
                        // 发送数据
                        mqService.convertAndSend(Cache.cloudMQQueueName, sendMsg);
                    } catch (Exception e) {
                        LOGGER.error("发送dict_customer数据异常，睡30秒", e);
                        Thread.sleep(30000);
                        continue;
                    }

                    // 更新数据库状态
                    dictService.updateCustomerUploadStatus(list);

                }

            } catch (Exception e) {
                LOGGER.error("sendCustomer发生异常", e);
            }
        }

    }

    /**
     * 替换机台编码
     *
     * @param dataList 数据集合
     */
    private void replaceMachinePrefix(List<Toiassets> dataList) {

        String replaceStr = Cache.factoryId.substring(0, 8);

        for (Toiassets toiasset : dataList) {
            String machineNo = toiasset.getAssetno();

            // 替换云端机台编码
            machineNo = Cache.factoryName + "-" + machineNo;
            toiasset.setAssetno(machineNo);
            // 替换工厂ID
            toiasset.setFactoryid(Cache.factoryId);

            String workshopPrefix = toiasset.getWorkshopid().substring(0, 8);
            String workshopid = toiasset.getWorkshopid().replaceAll(workshopPrefix, replaceStr);
            // 替换车间ID
            toiasset.setWorkshopid(workshopid);
            // 替换岗位ID
            String workstationPrefix = toiasset.getWorkstationid().substring(0, 8);
            String workstationid = toiasset.getWorkstationid().replaceAll(workstationPrefix, replaceStr);
            toiasset.setWorkstationid(workstationid);

            // 替换机台品牌ID
            String equiptypePrefix = toiasset.getEquiptypeid().substring(0, 8);
            String equiptypeid = toiasset.getEquiptypeid().replaceAll(equiptypePrefix, replaceStr);
            toiasset.setEquiptypeid(equiptypeid);

            // 替换机台型号ID
            String equipmodelPrefix = toiasset.getEquipmodelid().substring(0, 8);
            String euqipmodelid = toiasset.getEquipmodelid().replaceAll(equipmodelPrefix, replaceStr);
            toiasset.setEquipmodelid(euqipmodelid);

            // 机台型号前缀
            String equipNoPrefix = toiasset.getEquipno().substring(0, 8);
            String equipno = toiasset.getEquipno().replaceAll(equipNoPrefix, replaceStr);
            toiasset.setEquipno(equipno);
        }
    }

}
